// JORGE FERNANDO GOMEZ
// 1259371
// 189631
// LEC A1
// MARTIN MÜLLER
// D02
// YANG LIU


#include "util.h"

#line 12 "util.c"



static struct Streams * streamList = NULL;
static FILE ** sketchpad = NULL;


/********************************************
 *                                          *
 *           UTILITY FUNCTIONS              *
 *                                          *
 ********************************************/


/* addStream() adds a stream to a list of streams streamList. */
void addStream ( void * stream, char type, int issketchpad ) {
    struct Streams * newstream = malloc(sizeof(struct Streams));

    /* If I have time I'll try to implement a more global tracker. :( */
    if ( !newstream ) {
        fprintf(stderr, "draw2: %d, error.\n", __LINE__);
        exit(EXIT_FAILURE);
    }

    if ( issketchpad )
        sketchpad = stream;

    newstream->stream_type = type;
    newstream->streamptr = stream;

    newstream->next = streamList;
    streamList = newstream;
}

/* closeStreams() goes through a list of open streams
 * and calls either fclose() or pclose() depending on
 * stream type. */
void closeStreams ( void ) {

    struct Streams * freeing;
    for ( ; streamList != NULL; ) {

        if ( streamList->stream_type == 'f' )
            fclose( *(streamList->streamptr) );
        else if ( streamList->stream_type == 'p' )
            pclose( *(streamList->streamptr) );

        freeing = streamList;
        streamList = streamList->next;
        free(freeing);
    }
}

/* kill() takes amount numStacks of existing Figures, and frees
 * the corrseponding memory.  It also closes the program's open
 * streams.  It then prints an error message with the line number
 * numLine it was called with and exits EXIT_FAILURE. */
void kill ( FigStack * Figures, int numStacks, int numLine ) {

    int i;
    for ( i = 0; i < numStacks; i++ )
        destroyFigStack( &(Figures[i]) );

    fprintf(*sketchpad, "end\n");
    closeStreams();

    fprintf(stderr, "draw2: %d, error.\n", numLine);
    exit(EXIT_FAILURE);
}

/* getDoubles() skips blocks2skip blocks of non-whitespace
 * characters, and returns a double * doubles, which holds
 * two double numbers. */
double* getDoubles ( char * string, int blocks2skip, int count ) {

    if ( count == 0 )
        return (double *) 0;

    char * nextblock;       /* Pointer for strtod. */

    double * doubles = malloc( sizeof(double)*2 );

    if ( doubles == NULL ) {
        fprintf(stderr, "draw2: %d, error.\n", __LINE__);
        exit(EXIT_FAILURE);
    }

    int start = 0;          /* Keeps track of position on string. */
    int blocksFound = 0;
    int incrementFlag = 1;

    while ( 1 ) {
        if ( isspace( *(string + start) )) {

            /* Stop when enough blocks have been skipped. */
            if ( blocksFound == blocks2skip )
                break;

            if ( !incrementFlag )
                incrementFlag++;

            start++;
        }
        if ( !isspace( *(string + start) )) {
            if ( incrementFlag ) {
                blocksFound++;
                incrementFlag--;
            }
            start++;
        }
    }

    *doubles = strtod( string+start, &nextblock );

    int i;
    for ( i = 1; i < count; i++ )
        *(doubles + i) = strtod( nextblock, &nextblock );

    return doubles;
}

/* substr() takes string and creates a new string containig the characters
 * of string from index offset to index length.
 * Returns the resulting substring or the NULL pointer if string is smaller
 * than the provided offset + length */
char* substr (const char * string, int offset, int length) {

    int strLength = strlen(string);
    char * substring = malloc( sizeof(char)*(length+1) );

    if ( substring == NULL ) {
        fprintf(stderr, "draw2: %d, error.\n", __LINE__);
        exit(EXIT_FAILURE);
    }

    if ( strLength < (offset + length) )
        return(NULL);

    int i, j;
    for ( i = offset, j = 0; i < (offset+length); i++, j++) {
        *(substring + j) = *(string + i);
    }

    *(substring + length) = '\0';
    return substring;
}

/* chompim() takes lineString as argument and removes
 * any trailing whitespace from the string */
void chompim (char * lineString) {
    int len = strlen(lineString);
    int offset = 1;

    while ( isspace( *(lineString + len - offset) ))
        offset++;

    *(lineString+len-offset+1) = '\0';
}
